package cn.xiaolang.function.data_structure;

import org.junit.Assert;
import org.junit.Test;

/**
 * 自定义链表队列
 *
 * @author fuhw/Dean
 * @date 2020-04-10
 */
public class MockLinkedList<T> {

    Node<T> last;
    Node<T> first;
    int size;

    /**
     * 添加到链表尾部
     * @param t
     * @return
     */
    private boolean add(T t) {
        final Node<T> nl = last;
        Node<T> newNode = new Node<>(nl, null, t);
        last = newNode;
        if (null == nl) {
            first = newNode;
        } else {
            nl.next = newNode;
        }
        size++;
        return true;
    }

    /**
     * 移除队首
     * @return
     */
    private T remove() {
        if (null == first) {
            throw new RuntimeException("NoSuchElement");
        }
        final Node<T> f = first;
        final Node<T> second = f.next;
        T element = f.element;
        f.element = null;
        f.next = null;
        first = second;
        if (null == first) {
            last = null;
        } else {
            first.pre = null;
        }
        size--;
        return element;
    }


    static class Node<T> {
        private Node<T> pre;
        private Node<T> next;
        private T element;

        public Node(Node<T> pre, Node<T> next, T element) {
            this.pre = pre;
            this.next = next;
            this.element = element;
        }
    }

    @Override
    public String toString() {
        return super.toString();
    }


    @Test
    public void test() {
        MockLinkedList<Integer> list = new MockLinkedList<>();

        list.remove();
        int one = 1;
        int tow = 2;
        int three = 3;
        list.add(one);
        list.add(tow);
        list.add(three);

        Assert.assertEquals(list.size, three);
        Assert.assertEquals(list.first.element.intValue(), one);
        Assert.assertNull(list.first.pre);
        Assert.assertEquals(list.first.next.element.intValue(), tow);

        list.remove();

        Assert.assertEquals(list.first.element.intValue(), tow);
        Assert.assertNull(list.first.pre);
        Assert.assertEquals(list.first.next.element.intValue(), three);
    }

}